package com.doodle.common.utils;

import com.doodle.common.data.DataAdapter;
import com.doodle.common.drawable.AsyncDrawable;

public class DrawableDataAdapter implements DataAdapter {
	
	public static interface DrawableGetter {
		public abstract AsyncDrawable createDrawable(int index, AsyncDrawableJobExecutor jobExecutor);
		public abstract int getCount();
	}
	
	private AsyncDrawable mDrawables[];
	private AsyncDrawableJobExecutor mJobExecutor;
	private DrawableGetter mGetter;
	
	public DrawableDataAdapter(int cachSize, DrawableGetter getter) {
		mJobExecutor = AsyncDrawableJobExecutor.getInstance();
		mDrawables = new AsyncDrawable[cachSize * 2];
		mGetter = getter;
	}

	@Override
	public int size() {
		return mGetter.getCount();
	}

	@Override
	public void prepare(int index) {
		int modIndex = index % mDrawables.length;
		AsyncDrawable drawable =  mDrawables[modIndex];
		if (drawable == null) {
			mDrawables[modIndex] = mGetter.createDrawable(index, mJobExecutor);
		}
	}

	@Override
	public int start(int index) {
		AsyncDrawable drawable = mDrawables[index % mDrawables.length];
		if (drawable != null) {
			drawable.startLoad();
			return drawable.isRequestInProgress() ? 1 : 0;
		} else {
			Utils.log("Data start but not prepared: %d", index);
			return 0;
		}
	}

	@Override
	public void cancel(int index) {
		AsyncDrawable drawable = mDrawables[index % mDrawables.length];
		if (drawable != null) {
			drawable.cancelLoad();
		} else {
			Utils.log("Data cancel but not prepared: %d", index);
		}
	}

	@Override
	public void free(int index) {
		int modIndex = index % mDrawables.length;
		AsyncDrawable drawable = mDrawables[modIndex];
		if (drawable != null) {
			drawable.recycle();
		} else {
			Utils.log("Data free but not prepared: %d", index);
		}
		mDrawables[modIndex] = null;
	}

	@Override
	public void remove(int index) {
	}

	@Override
	public long getDataId(int index) {
		return index;
	}

	@Override
	public Object getDataObject(int index) {
		return mDrawables[index % mDrawables.length];
	}

	@Override
	public void setDataObject(int index, Object data) {
		mDrawables[index % mDrawables.length] = (AsyncDrawable)data;
	}

	@Override
	public void freeDataObject(Object data) {
		if (data != null) {
			((AsyncDrawable)data).recycle();
		}
	}
	
	public AsyncDrawable getDrawable(int index) {
		int modIndex = index % mDrawables.length;
		AsyncDrawable drawable =  mDrawables[modIndex];
		if (drawable == null) {
			drawable = mGetter.createDrawable(index, mJobExecutor);
			mDrawables[modIndex] = drawable;
		}
		return drawable;
	}

}
